Event emitter
Async event emitter with support for typed events
This module is extracted from AdonisJs. It is an Async event emitter with support for Typed events when using typescript.
Features
- Asynchronous
- Support for Typed events (when using Typescript)
- Comes with fake emitter for testing
Table of contents
Usage
Install the package from npm registry as follows:
npm i @poppinss/events
yarn add @poppinss/events
And then use it as follows:
import { Emitter } from '@poppinss/events'
const emitter = new Emitter()
emitter.on('signup', async (data) => {
})
emitter.emit('signup', { id: 1, email: 'foo@bar.com' })
Asynchronous
Node.js inbuilt event emitter is synchronous and blocks the event loop while emitting events. On the other hand, this module relies on emittery to emit events asynchronously.
Typed events
When using Typescript, you can attach data types to a event name and the Typescript compiler will complain, if types aren't the same.
import { Emitter } from '@poppinss/events'
type EventsMap = {
'new:user': { id: number },
}
const emitter = new Emitter<EventsMap>()
emitter.emit('new:user', { id: 1 })
emitter.emit('new:user', 1)
Just like the emit
method, all other methods enforce types on typed events.
const emitter = new Emitter<EventsMap>()
emitter.on('new:user', (user) => {
})
emitter.once('new:user', (user) => {
})
Fake emitter
When writing tests, you may want to suppress the events and instead run assertions to ensure that your code is emitting right events with correct data.
You can do this by using the FakeEmitter
instance during tests.
Application code
import { EmitterContract } from '@poppinss/events'
export default class UserController {
constructor (protected emitter) {}
create () {
const user = makeSomeDbCall()
this.emitter.emit('new:user', user)
}
}
When writing tests, you can pass the FakeEmitter
, instead of the real emitter instance.
Test
import { FakeEmitter } from '@poppinss/events'
import UserController from './UserController'
const emitter = new FakeEmitter()
new UserController(emitter).create()
assert.deepEqual(emitter.events, [{
event: 'new:user',
data: user,
}])
emitter.clear()
AdonisJs usage
When using with AdonisJs, you can also define listeners as a reference to the IoC container binding. For example:
Event.on('new:user', 'User.signup')
Event.off('new:user', 'User.signup')
AdonisJs will make an instance of app/Listeners/User.ts
file and will call the signup method on it. This keeps your events file clean, since you can abstract the listeners code to dedicated files.
Also, you can define a custom namespace to lookup listeners from.
Event.namespace('App/MyListeners')
Now AdonisJs will look inside the MyListeners
directory vs Listeners
.
API
Following are the autogenerated files via Typedoc
Maintainers
Harminder virk